package cinema.Controller;

import cinema.Dao.ReservationDAO;
import cinema.Dao.RowDAO;
import cinema.Dao.SeatDAO;
import cinema.Dao.TimeTableDAO;
import cinema.Entity.Reservation;
import cinema.Entity.Row;
import cinema.Entity.Seat;
import cinema.Entity.TimeTable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@ManagedBean(name = "seatBean")
@SessionScoped
public class ChooseSeatController implements Serializable {

    @Inject
    RowDAO rowDAO;

    @Inject
    ReservationDAO reservationDAO;

    @Inject
    SeatDAO seatDAO;

    @Inject
    TimeTableDAO timeTableDAO;

    private Row row;
    private TimeTable timeTable;
    private List<List<DrawableSeat>> seats;
    private List<Seat> reservedSeats;
    private List<Map.Entry<Integer, Integer>> seatList;
    private int seatCount, timeTableID;
    private Date startTime;
    private static int chosenSeats;

    public String process() {
        FacesContext fc = FacesContext.getCurrentInstance();
        Map<String, String> params = fc.getExternalContext().getRequestParameterMap();
        int roomID = Integer.parseInt(params.get("roomId"));
        DateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);
        try{
            startTime = format.parse(params.get("startTime"));
        }
        catch(Exception e){}
        chosenSeats = 0;

        reservedSeats = new ArrayList<Seat>();
        timeTableID = Integer.parseInt(params.get("timeTableID"));
        getReservedSeats(timeTableID);

        timeTable = timeTableDAO.findById(timeTableID);

        List<Row> list = rowDAO.findAll();

        for (Row row : list) {
            if (row.getRoom().getRoomId() == roomID)
                this.row = row;
        }

        initSeats();

        return "chooseSeats?faces-redirect=true";
    }

    private void getReservedSeats(int timeTableID) {
        List<Reservation> allReservations = reservationDAO.findAll();
        List<Integer> reservationIDs = new ArrayList<Integer>();

        for (Reservation r : allReservations) {
            if (r.getTimeTable().getTId() == timeTableID)
                reservationIDs.add(r.getRid());
        }

        List<Seat> allSeats = seatDAO.findAll();

        for (Seat s : allSeats) {
            if (reservationIDs.contains(s.getReservation().getRid()))
                reservedSeats.add(s);
        }
    }

    private void initSeats() {
        seatCount = row.getSeatCount();
        int rowCount = row.getRowNumber();

        this.seats = new ArrayList<List<DrawableSeat>>();

        for (int i = 0; i < rowCount; ++i) {
            this.seats.add(new ArrayList<DrawableSeat>());
            this.seats.get(i).add(new DrawableSeat("" + (i + 1), "#464646"));

            for (int j = 1; j <= seatCount; ++j) {
                if (isSeatReserved(i, j))
                    this.seats.get(i).add(new DrawableSeat(i + 1, "" + j, "red"));
                else
                    this.seats.get(i).add(new DrawableSeat(i + 1, "" + j, "#74b807"));
            }

            this.seats.get(i).add(new DrawableSeat("" + (i + 1), "#464646"));
        }
    }

    private boolean isSeatReserved(int row, int column) {
        for (Seat s : reservedSeats) {
            if (s.getRow() == row && s.getSeat() == column)
                return true;
        }

        return false;
    }

    public void reserve(DrawableSeat seat) {
        if (seat.color.equals("#74b807")) {
            seat.color = "#E68A00";
            ++chosenSeats;
        } else {
            seat.color = "#74b807";
            --chosenSeats;
        }
    }

    public boolean isDisabled(DrawableSeat seat) {
        return seat.getColor().equals("red");
    }

    public boolean isSeatChosen() {
        return chosenSeats > 0;
    }

    public void finalizeSeats() {
        seatList = new java.util.ArrayList<Map.Entry<Integer, Integer>>();
        DrawableSeat seat;

        for (int i = 0; i < row.getRowNumber(); ++i) {
            for (int j = 1; j <= seatCount; ++j) {
                seat = this.seats.get(i).get(j);
                if (seat.getColor().equals("#E68A00"))
                    seatList.add(new java.util.AbstractMap.SimpleEntry<Integer, Integer>
                            (seat.getRowNumber(), Integer.parseInt(seat.getSeatNumber())));
            }
        }
    }

    public Row getRow() {
        return row;
    }

    public int getSeatCount() {
        return seatCount;
    }

    public List<List<DrawableSeat>> getSeats() {
        return seats;
    }

    public Date getStartTime() {
        return startTime;
    }

    public List<Map.Entry<Integer, Integer>> getSeatList() {
        return seatList;
    }

    public int getTimeTableID() {
        return timeTableID;
    }

    public TimeTable getTimeTable() { return timeTable; }

    public class DrawableSeat {

        int rowNumber;
        private String seatNumber, color;

        public DrawableSeat(String seatNumber, String color) {
            this.rowNumber = 0;
            this.seatNumber = seatNumber;
            this.color = color;
        }

        public DrawableSeat(int rowNumber, String seatNumber, String color) {
            this.rowNumber = rowNumber;
            this.seatNumber = seatNumber;
            this.color = color;
        }

        public int getRowNumber() {
            return rowNumber;
        }

        public String getSeatNumber() {
            return seatNumber;
        }

        public String getColor() {
            return color;
        }
    }
}
